﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using Fast.Framework.Interfaces;
using Fast.Framework.Extensions;
using Fast.Framework.Models;

namespace Fast.Framework
{

    /// <summary>
    /// 插入实现类
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class InsertProvider<T> : IInsert<T> where T : class
    {

        /// <summary>
        /// Ado
        /// </summary>
        private readonly IAdo ado;

        /// <summary>
        /// 插入建造者
        /// </summary>
        public IInsertBuilder InsertBuilder { get; }

        /// <summary>
        /// 构造方法
        /// </summary>
        /// <param name="ado">ado</param>
        /// <param name="insertBuilder">插入建造者</param>
        public InsertProvider(IAdo ado, IInsertBuilder insertBuilder)
        {
            this.ado = ado;
            InsertBuilder = insertBuilder;
        }

        /// <summary>
        /// 作为
        /// </summary>
        /// <param name="tableName">表名称</param>
        /// <returns></returns>
        public IInsert<T> As(string tableName)
        {
            InsertBuilder.TableName = DbSymbolMapper.identify[ado.DbOptions.DbType].Insert(1, tableName);
            return this;
        }

        /// <summary>
        /// 执行异步
        /// </summary>
        /// <returns></returns>
        public async Task<int> ExecuteAsync()
        {
            if (!InsertBuilder.IsBatch)
            {
                return await ado.ExecuteNonQueryAsync(this.ToString(), ado.SqlParametersBuild(InsertBuilder.Parameters));
            }
            var dbParameterlist = InsertBuilder.ParametersList.Select(s => ado.SqlParametersBuild(s)).ToList();
            return await ado.ExecuteNonQueryAsync(this.ToString(), dbParameterlist);
        }

        /// <summary>
        /// 执行返回自增ID异步
        /// </summary>
        /// <returns></returns>
        public Task<int> ExecuteReturnIdentityAsync()
        {
            if (InsertBuilder.IsBatch)
            {
                throw new NotSupportedException("批量插入不支持返回自增ID");
            }
            var sql = this.ToString();
            if (ado.DbOptions.DbType == DbType.SQLServer || ado.DbOptions.DbType == DbType.MySQL)
            {
                sql = $"{(sql.LastIndexOf(';') == -1 ? $"{sql};" : sql)}SELECT @@IDENTITY;";
            }
            else if (ado.DbOptions.DbType == DbType.SQLite)
            {
                sql = $"{(sql.LastIndexOf(';') == -1 ? $"{sql};" : sql)}SELECT LAST_INSERT_ROWID();";
            }
            else
            {
                throw new NotSupportedException($"{DbType.Oracle}数据库不支持返回自增ID");
            }
            return ado.ExecuteScalarAsync<int>(sql, ado.SqlParametersBuild(InsertBuilder.Parameters));
        }

        /// <summary>
        /// 到字符串
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return InsertBuilder.ToString();
        }
    }
}
